<?php
/**
 * Summary
 * 
 * Adaptar a Memchached usando la extensión de Php5 Memcache (sin 'D')
 */
namespace SubMemory\Cache;

use SubMemory\Cache\CacheInterface;


/**
 * MemcacheCache
 */
class MemcacheCache implements CacheInterface {

    /**
     * Servidores Memchached
     * @var array
     */
    protected $_servers = array();
    /**
     * Puerto Memcached por defecto 11211, si uno no es especificado.
     * @var int 
     */
    private   $_defaultPort = 11211;
    /**
     * Host por defecto.
     * @var string 
     */
    private   $_defaultHost = "localhost";
    /**
     * Mensaje de error
     * @var string
     */
    public    $error;

    /**
     * Constructor
     */
    public function __construct(array $servers = null) {
        $this->_servers = $servers;
               
//        ini_set("memcache.hash_strategy","consistent");
//        ini_set("memcache.protocol","ascii");
//        ini_set("memcache.redundancy",2);
//        ini_set("memcache.session_redundancy",3);
//        ini_set("memcache.allow_failover",1); //encendido failover
//        ini_set("memcache.max_failover_attempts",2); //numero de servidores
        
        $this->cache = new \Memcache();

        if (is_null($servers) || count($servers)==0) {
            $result = $this->cache->addServer(
                    $host= $this->_defaultHost
                    , $port = $this->_defaultPort
                    , $persistent = FALSE
                    , $weight = 1
                    , $timeout = 1
                    , $retry_interval = 1
                    ,$status = -1
                    ,array($this,"onFailure")

                    );
            if($result){
                $this->error="OK. Servidor por defecto está conectado";
            }
        } else {
            foreach($this->_servers as $server){
                if(isset($server["host"])){
                    $host = $server["host"];
                    $port = (isset($server["port"])?$server["port"]:$this->_defaultPort  );
                              
                    if($this->cache->connect($host,$port)){
                          $this->cache->addServer(
                               $host
                             , $port
                             , $persistent = TRUE
                             , $weight = 1
                             , $timeout = 1
                             , $retry_interval = 2
                             ,$status = -1
                             ,array($this,"onFailure")
                         );
                        $this->error = "Ok. Memcached $host:$port se unio al pool";  
                    }else{
                        $this->error = "Memcached $host:$port no se pudo unir";
                    }        
                
                }
            }
        }
    }

    /**
     * Se ejecuta durante una falla.
     * 
     * @param string $host
     * @param int $port
     */
    public function onFailure($host="",$port=0){
            $this->error= "Falló Memcached {$host}:{$port}";
    }

    

    /**
     * Destructor
     */
    public function __destruct() {
        $this->cache->close();
    }

    //end __destruct()
    
    /**
     * Añade un nuevo ítem asociado a una nueva clave. O Modifica uno existente.
     * @param string $key
     * @param string $value
     * @param int $expirationtime
     */
    public function set($key, $value, $expirationtime = 3600) {
        
        return $this->cache->set($key, $value, 0,$expirationtime);
    }

    /**
     * Obtener valor de una clave.
     * @param string $key
     */
    public function get($key) {
        return $this->cache->get($key);
    }

    /**
     * Borrar una clave
     * @param string $key
     */ 
    public function delete($key) {
        return $this->cache->delete($key);
    }
    
    /**
      * Cerrar conección 
      * @return boolean
      */
    public function close(){
         return $this->cache->close();
    }
    
     /**
      * Recolector de basura.
      * @param int $maxlifetime
      * @return boolean
      */
    public function gc($maxlifetime){
        return true;
    }

}

//end class
?>
